package com.xltt.watchlauncher3.view.menu;

import android.content.Context;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.view.View;
import android.widget.ImageView;

import com.xltt.watchlauncher3.R;


@SuppressWarnings({"WeakerAccess", "unused"})
public class LayoutManager extends ViewPagerLayoutManager {
    private static final String TAG = "LayoutManager";
    private int itemSpace;
    private float minScale;
    private float moveSpeed;

    public LayoutManager(Context context, int itemSpace) {
        this(new Builder(context, itemSpace));
    }

    public LayoutManager(Context context, int itemSpace, int orientation) {
        this(new Builder(context, itemSpace).setOrientation(orientation));
    }

    public LayoutManager(Context context, int itemSpace, int orientation, boolean reverseLayout) {
        this(new Builder(context, itemSpace).setOrientation(orientation).setReverseLayout(reverseLayout));
    }

    public LayoutManager(Builder builder) {
        this(builder.context, builder.itemSpace, builder.minScale, builder.orientation,
                builder.maxVisibleItemCount, builder.moveSpeed, builder.distanceToBottom,
                builder.reverseLayout);
    }

    private LayoutManager(Context context, int itemSpace, float minScale, int orientation,
                          int maxVisibleItemCount, float moveSpeed, int distanceToBottom,
                          boolean reverseLayout) {
        super(context, orientation, reverseLayout);
        setEnableBringCenterToFront(true);
        setDistanceToBottom(distanceToBottom);
        setMaxVisibleItemCount(maxVisibleItemCount);
        this.itemSpace = itemSpace;
        this.minScale = minScale;
        this.moveSpeed = moveSpeed;
    }

    public int getItemSpace() {
        return itemSpace;
    }

    public float getMinScale() {
        return minScale;
    }

    public float getMoveSpeed() {
        return moveSpeed;
    }

    public void setItemSpace(int itemSpace) {
        assertNotInLayoutOrScroll(null);
        if (this.itemSpace == itemSpace) return;
        this.itemSpace = itemSpace;
        removeAllViews();
    }

    public void setMinScale(float minScale) {
        assertNotInLayoutOrScroll(null);
        if (minScale > 1f) minScale = 1f;
        if (this.minScale == minScale) return;
        this.minScale = minScale;
        requestLayout();
    }

    public void setMoveSpeed(float moveSpeed) {
        assertNotInLayoutOrScroll(null);
        if (this.moveSpeed == moveSpeed) return;
        this.moveSpeed = moveSpeed;
    }

    @Override
    protected float setInterval() {
        return (mDecoratedMeasurement - itemSpace);
    }

    @Override
    protected void setItemViewProperty(View itemView, float targetOffset) {
        float scale = calculateScale(targetOffset + mSpaceMain,2.f);
        itemView.setScaleX(scale);
        itemView.setScaleY(scale);

        ImageView view = itemView.findViewById(R.id.image);
        View coverView = itemView.findViewById(R.id.coverView);
        ColorMatrix matrix = new ColorMatrix();
        float value = calculateScale(targetOffset + mSpaceMain,9.f);
        float alpha = calculateScale(targetOffset + mSpaceMain,4.f);
        matrix.setSaturation(value);
        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
        view.setColorFilter(filter);

        coverView.setAlpha(1.f - alpha);
    }

    @Override
    protected float getDistanceRatio() {
        if (moveSpeed == 0) return Float.MAX_VALUE;
        return 1 / moveSpeed;
    }

    @Override
    protected float setViewElevation(View itemView, float targetOffset) {
        return itemView.getScaleX() * 5;
    }

    private float calculateScale(float x,float value) {
        float deltaX = Math.abs(x - (mOrientationHelper.getTotalSpace() - mDecoratedMeasurement) / 2f);
        return (minScale - 1) * deltaX / (mOrientationHelper.getTotalSpace() / value) + 1f;
    }

//    private float calculateScale2(float x) {
//        float deltaX = Math.abs(x - (mOrientationHelper.getTotalSpace() - mDecoratedMeasurement) / 2f);
//        return (minScale - 1) * deltaX / (mOrientationHelper.getTotalSpace() / 8f) + 1f;
//    }
//
//    private float calculateScale3(float x) {
//        float deltaX = Math.abs(x - (mOrientationHelper.getTotalSpace() - mDecoratedMeasurement) / 2f);
//        return (minScale - 1) * deltaX / (mOrientationHelper.getTotalSpace() / 4f) + 1f;
//    }

    public static class Builder {
        private static final float DEFAULT_SPEED = 1f;
        private static final float MIN_SCALE = 0.5f;

        private Context context;
        private int itemSpace;
        private int orientation;
        private float minScale;
        private float moveSpeed;
        private int maxVisibleItemCount;
        private boolean reverseLayout;
        private int distanceToBottom;

        public Builder(Context context, int itemSpace) {
            this.itemSpace = itemSpace;
            this.context = context;
            orientation = HORIZONTAL;
            minScale = MIN_SCALE;
            this.moveSpeed = DEFAULT_SPEED;
            reverseLayout = false;
            maxVisibleItemCount = ViewPagerLayoutManager.DETERMINE_BY_MAX_AND_MIN;
            distanceToBottom = ViewPagerLayoutManager.INVALID_SIZE;
        }

        public Builder setOrientation(int orientation) {
            this.orientation = orientation;
            return this;
        }

        public Builder setMinScale(float minScale) {
            this.minScale = minScale;
            return this;
        }

        public Builder setReverseLayout(boolean reverseLayout) {
            this.reverseLayout = reverseLayout;
            return this;
        }

        public Builder setMoveSpeed(float moveSpeed) {
            this.moveSpeed = moveSpeed;
            return this;
        }

        public Builder setMaxVisibleItemCount(int maxVisibleItemCount) {
            this.maxVisibleItemCount = maxVisibleItemCount;
            return this;
        }

        public Builder setDistanceToBottom(int distanceToBottom) {
            this.distanceToBottom = distanceToBottom;
            return this;
        }

        public LayoutManager build() {
            return new LayoutManager(this);
        }
    }
}
